namespace Vanilla.UI

import System

// TODO:
//   * add draggable scroll thingies

// V SCROLLER
class VScroller (Column):
	class UpButton (Button):
		def constructor (p as Box, c as callable):
			super(p, c)
	class DownButton (Button):
		def constructor (p as Box, c as callable):
			super(p, c)
	class Grabby (Gadget):
		def constructor (p as VScroller):
			super(p)

	override MinSize as Size:
		get:
			return Size(15,60)
	
	_rs as double = 0
	public RealSize as double:
		get:
			return _rs
		set:
			return if cast(int,value) == cast(int,_rs)
			print "RealSize was ${_rs} now ${value}"
			_rs = value
			Reset()
	
	_sp as double = 0
	public ScrollPosition as double:
		get:
			return _sp
		set:
			return if value == _sp
			value = 0 if value < 0
			value = RealSize if value > RealSize
			_sp = value
			OnScroll(value)
			Pack()

	Up as UpButton
	Down as DownButton
	Bar as Grabby
	
	OnScroll as callable(double)
	
	def constructor (p as Box, c as callable(double)):
		super(p)
		Up = UpButton(self,{c(ScrollPosition-=25)})
		Down = DownButton(self,{c(ScrollPosition+=25)})
		Bar = Grabby(self) // BAAAAAAAAAAHAHAHAHAHAHAHAHAHAHAHA
		OnScroll = c
	
	def Reset ():
		ScrollPosition = 0
	
	def Arrange ():
		return if Up == null or Down == null or Bar == null
		
		size = (Size.Height-30)*(Size.Height / RealSize)
		center = (ScrollPosition / RealSize) * (Size.Height - 30 - size)
		
		print "center=${center} sp=${ScrollPosition} rs=${RealSize} h=${Size.Height} sz=${size}"
		
		Bar.Rect = Rect(0, 15 + center, Size.Width, 15 + center + size)
		
		Up.Rect = Rect(0,0,Size.Width,15)
		Down.Rect = Rect(0,Size.Height-15,Size.Width,Size.Height)

// H SCROLLER
class HScroller (Row):
	class LeftButton (Button):
		def constructor (p as Box, c as callable):
			super(p, c)
	class RightButton (Button):
		def constructor (p as Box, c as callable):
			super(p, c)
	class Grabby (Gadget):
		def constructor (p as HScroller):
			super(p)

	override MinSize as Size:
		get:
			return Size(60,15)
	
	_rs as double = 0
	public RealSize as double:
		get:
			return _rs
		set:
			return if value == _rs
			_rs = value
			Reset()
	
	_sp as double = 0
	public ScrollPosition as double:
		get:
			return _sp
		set:
			return if value == _sp
			value = 0 if value < 0
			value = RealSize if value > RealSize
			_sp = value
			OnScroll(value)
			Pack()
	
	Left as LeftButton
	Right as RightButton
	Bar as Grabby
	
	OnScroll as callable(double) = def (d as double):
		pass
	
	def constructor (p as Box, c as callable(double)):
		super(p)
		Left = LeftButton(self, {ScrollPosition-=(RealSize*0.1)})
		Right = RightButton(self, {ScrollPosition+=(RealSize*0.1)})
		Bar = Grabby(self)
		OnScroll = c
	
	def Reset ():
		ScrollPosition = 0
	
	def Arrange ():
		return if Left == null or Right == null or Bar == null
		
		size = 40
		center = (ScrollPosition / RealSize) * (Size.Width - 30 - size)
		
		Bar.Rect = Rect(15 + center , 0, 15 + center + size, Size.Height)
		
		Left.Rect = Rect(0,0,15,Size.Height)
		Right.Rect = Rect(Size.Width-15,0,Size.Width,Size.Height)

// SCROLL FRAME
class ScrollFrame (Frame):
	override MinSize as Size:
		get:
			return Size(60,60)

	enum Option:
		Yes
		No
		Auto
	
	_ev as Option = Option.Auto
	public EnableVertical as Option:
		get:
			return _ev
		set:
			_ev = value
			Setup()
			
	_eh as Option = Option.Auto
	public EnableHorizontal as Option:
		get:
			return _eh
		set:
			_eh = value
			Setup()
	
	public Vertical as VScroller
	public Horizontal as HScroller
	
	_co as Position = Position(0,0)
	public ChildOffset as Position:
		get:
			return _co
		set:
			_co = value
			Pack()
			Redraw()
	
	def constructor (p as Box, h as Option, v as Option):
		super(p)
		EnableHorizontal = h
		EnableVertical = v
	
	def constructor (p as Box):
		self(p, Option.Auto, Option.Auto)
	
	
	// Creates/destroys scrollers if need be
	def Setup ():
		return if Child == null
	
		old_child = Child
		//if EnableVertical == Option.No and Vertical != null:
		//	
		PausePacking()
		if EnableVertical == Option.Yes or (Child.MinSize.Height > Size.Height and EnableVertical == Option.Auto) and Vertical == null:
			Vertical = VScroller(self, {v as double | ChildOffset = Position(ChildOffset.X, -v)})
		if EnableHorizontal == Option.Yes and Horizontal == null:
			Horizontal = HScroller(self, {v as double | ChildOffset = Position(-v, ChildOffset.Y)})
		ResumePacking()
		
		if old_child != Child:
			child = null
		
		if Child != null:
			if Vertical != null:
				Vertical.RealSize = ChildSize.Height
			if Horizontal != null:
				Horizontal.RealSize = ChildSize.Width
	
	_csz as Size
	ChildSize as Size:
		get:
			return _csz
		set:
			return if _csz == value
			_csz = value
			Setup()
			Pack()
	
	override def Arrange ():
		//ChildSize = Size(Math.Max(Math.Max(Child.MinSize.Width,ChildSize.Width),Size.Width),
		//                 Math.Max(Math.Max(Child.MinSize.Height,ChildSize.Height),Size.Height))
	
		max_x = Size.Width
		max_y = Size.Height
		
		Child.SendToBack() unless Child == null
		
		if Horizontal != null:
			max_y = Size.Height - Horizontal.MinSize.Height
		if Vertical != null:
			Vertical.RealSize = Child.Size.Height unless Child == null
			max_x = Size.Width - Vertical.MinSize.Width
			Vertical.Rect=Rect(max_x, 0, Size.Width, max_y)
		if Horizontal != null:
			Horizontal.RealSize = Child.Size.Width unless Child == null
			Horizontal.Rect=Rect(0, max_y, max_x, Size.Height)
		
		if Child != null:
			Child.SendToBack()
			Child.Rect = Rect(ChildOffset.X, ChildOffset.Y,
			                  Math.Max(Child.MinSize.Width+ChildOffset.X, max_x),
			                  Math.Max(Child.MinSize.Height+ChildOffset.Y, max_y))
		
